package com.boot.ys.mybatisplus.redis;

import com.boot.ys.mybatisplus.entity.Abc;
import org.apache.commons.collections4.Get;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * SpringBoot 整合使用redis
 */
@RestController
@RequestMapping("/redis")
public class RedisTemplateDemo {

//    redisTemplate.opsForList();　	// 操作list
//    redisTemplate.opsForHash();　	// 操作hash
//    redisTemplate.opsForValue();	// 操作字符串
//    redisTemplate.opsForSet();　　// 操作set
//    redisTemplate.opsForZSet();　	// 操作有序set

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 测试字符串类型存数据
     */
    @GetMapping("/createRedisString")
    public String createRedisString(){
        //向数据库中保存 name heima
        redisTemplate.opsForValue().set("age","13");
//        //相关数据保存 name1 heima1  有效时间为10s
        redisTemplate.opsForValue().set("name1","heima1",10, TimeUnit.SECONDS);
//        //替换 heima        heXXa  offset 索引位置是从0开始
        redisTemplate.opsForValue().set("age","0",2);
//        //当key不存在的时候，执行保存操作；当key存在时，什么都不做
        redisTemplate.opsForValue().setIfAbsent("name","heima");
//        //批量保存
        Map<String,String> map = new HashMap<>();
        map.put("name2","heima2");
        map.put("name3","heima3");
        map.put("name4","heima4");
        redisTemplate.opsForValue().multiSet(map);
//        //追加 当key存在时，会执行追加操作；当key不存在时，会执行保存操作
        redisTemplate.opsForValue().append("name5","heima");
        return "true";
    }
    /**
     * 测试字符串取数据
     */
    @GetMapping("/getRedisString")
    public String getRedisString(){
        //得到指定的值
        Object age = redisTemplate.opsForValue().get("age");
        System.out.println(age);
//        //批量获取，这是里面有这几条数据，就快要批量取出来
        List<String> keys = new ArrayList<>();
        keys.add("name2");
        keys.add("name3");
        keys.add("name4");
        List<String> values = redisTemplate.opsForValue().multiGet(keys);
        for (String s : values) {
            System.out.println(s);
        }
//        //根据key获取value的长度
        Long size = redisTemplate.opsForValue().size("name");
        System.out.println(size);
        System.out.println("=============================================================");
        redisTemplate.opsForValue().set("age","18");
//        //在原有基础上自增1
        redisTemplate.opsForValue().increment("age");
        System.out.println(redisTemplate.opsForValue().get("age"));
//        //自增6
        redisTemplate.opsForValue().increment("age",6);
        System.out.println(redisTemplate.opsForValue().get("age"));
//        //自减
        redisTemplate.opsForValue().decrement("age");
        Boolean a = redisTemplate.delete("age");
        System.out.println(a);
        return "true";
    }

    /**
     * 测试List集合
     */
    @GetMapping("/createRedisList")
    public String createRedisList(){
        //从左边添加一个元素
        redisTemplate.opsForList().leftPush("students","zhangshan");
        //从左边添加多个元素
        redisTemplate.opsForList().leftPush("students","lishi","wangwu");

        //从右边添加一个元素
        redisTemplate.opsForList().rightPush("students","zhangshan1");
        //从右边添加多个元素
        redisTemplate.opsForList().rightPush("students","lishi1","wangwu1");
        //根据key和元素索引进行查询
        //0和正数代表从左边开始
        //负数代表从右边开始
        String students = (String) redisTemplate.opsForList().index("students", 1);
        System.out.println(students);

        String students1 = (String) redisTemplate.opsForList().index("students", -1);
        System.out.println(students1);

        //范围查询
        //根据key 【start,end】 包括首尾
        List<String> students2 = redisTemplate.opsForList().range("students", 0, 2);
        for (String s : students2) {
            System.out.println(s);
        }
        //从左边删除第一个元素
//        String s = (String)redisTemplate.opsForList().leftPop("students");
        //从右边删除第一个元素
//        String s1 = (String) redisTemplate.opsForList().rightPop("students");

        //count > 0; 删除左边起第几个等于指定值的元素
        //count < 0; 删除右边起第几个等于指定值的元素
        //count = 0; 删除所有等于value的元素
        //删除左边起第二个wangwu
//        redisTemplate.opsForList().remove("students",2,"wangwu");
        return "true";
    }

    /**
     * 测试Hash
     */
    @GetMapping("/createRedisHash")
    public String createRedisHash(){

        //往指定 Hash 中放入一个 key，value：
        redisTemplate.opsForHash().put("maps", "name", "zhangsan");
        Map<String, String> map = new HashMap<>();
        map.put("age", "12");
        map.put("bir", "2012-12-12");
        redisTemplate.opsForHash().putAll("maps", map); // 放入多个key, value

        String vv = (String) redisTemplate.opsForHash().get("maps", "name");
        System.out.println("vv----"+vv);

        List<Object> values = redisTemplate.opsForHash().multiGet("maps", Arrays.asList("name", "age"));
        values.forEach(value -> System.out.println(value));

        Set<Object> keys = redisTemplate.opsForHash().keys("maps"); // 获取所有keys
        System.out.println("keys"+keys);
        List<Object> vals = redisTemplate.opsForHash().values("maps"); // 获取所有values
        System.out.println("vals"+vals);

        return "true";
    }

    /**
     * 测试Set类型
     */
    @GetMapping("/createRedisSet")
    public String createRedisSet(){
        //增加
        redisTemplate.opsForSet().add("Students","zhangsan","lishi","wangwu","Zhangsan");

        //查询------------查询所有元素
        Set<String> students = redisTemplate.opsForSet().members("Students");
        for (String student : students) {
            System.out.println(student);
        }
        //随机获取一个元素
        Object students1 = redisTemplate.opsForSet().randomMember("Students");
        System.out.println(students1);
        //随机获取多个元素【可能会重复】
        List<String> list = redisTemplate.opsForSet().randomMembers("Students", 2);
        for (String s : list) {
            System.out.println(s);
        }

        //---删除-----移除元素，并返回移除成功个数
        Long remove = redisTemplate.opsForSet().remove("Students", "zhangsan", "wangwu");
        System.out.println(remove);
        //随机移除指定集合中的多少个元素
        List<String> students2 = redisTemplate.opsForSet().pop("Students", 2);
        for (String student : students2) {
            System.out.println(student);
        }

        //---------多集合操作----------------
        redisTemplate.opsForSet().add("names1","zhangsan","li","wangwu");
        redisTemplate.opsForSet().add("names2","zhangsan","li","zhaoliu");
        //取交集
        Set<String> intersect = redisTemplate.opsForSet().intersect("names1", "names2");
        for (String s : intersect) {
            System.out.println(s);
        }
        //取并集
        Set<String> union = redisTemplate.opsForSet().union("names1", "names2");
        for (String s : union) {
            System.out.println(s);
        }
        //取差集[第一个集合中存在，但第二个集合中不存在的元素]
        Set<String> difference = redisTemplate.opsForSet().difference("names2", "names1");
        for (String s : difference) {
            System.out.println(s);
        }

        return "true";
    }

    /**
     * 测试ZSet类型
     * TestRedisZSet
     */
    @GetMapping("/createRedisZSet")
    public String createRedisZSet(){
        redisTemplate.opsForZSet().add("student","wangwu",60);
        redisTemplate.opsForZSet().add("student","lishi",100);
        redisTemplate.opsForZSet().add("student","zhangshan",90);
        // 增加分数
        redisTemplate.opsForZSet().incrementScore("student","wangwu",30);
        // 减少分数
        redisTemplate.opsForZSet().incrementScore("student","wangwu",-50);
        //查询一个元素的分数
        Double score = redisTemplate.opsForZSet().score("student", "wangwu");
        System.out.println(score);
        //查询一个元素在集合中的排名  排名从0开始
        Long rank = redisTemplate.opsForZSet().rank("student", "zhangshan");
        System.out.println(rank);
        //根据排名区间获取元素列表
        Set<String> students = redisTemplate.opsForZSet().range("student",0,2);
        for (String student : students) {
            System.out.println(student);
        }
        System.out.println("-------------");
        Set<ZSetOperations.TypedTuple<String>> student = redisTemplate.opsForZSet().rangeWithScores("student", 0, 2);
        for (ZSetOperations.TypedTuple<String> stringTypedTuple : student) {
            System.out.println(stringTypedTuple.getValue()+"同学，得了"+stringTypedTuple.getScore()+"分");
        }
        System.out.println("-----------------------------");
        //根据排名区间获取元素列表
        Set<String> students1 = redisTemplate.opsForZSet().rangeByScore("student",50,100);
        for (String student1 : students1) {
            System.out.println(student1);
        }
        System.out.println("-------------");
        Set<ZSetOperations.TypedTuple<String>> student1 = redisTemplate.opsForZSet().rangeByScoreWithScores("student", 50, 100);
        for (ZSetOperations.TypedTuple<String> stringTypedTuple : student1) {
            System.out.println(stringTypedTuple.getValue()+"同学，得了"+stringTypedTuple.getScore()+"分");
        }
        //统计一个集合中元素
        Long student11 = redisTemplate.opsForZSet().zCard("student");
        System.out.println(student);
        //根据一个分数区间统计元素数量
        Long count = redisTemplate.opsForZSet().count("student", 50, 100);
        System.out.println(count);
        //根据key-value删除 value允许传入多个
        redisTemplate.opsForZSet().remove("student","zhangsan","lisi");
        //根据排名区间删除
        redisTemplate.opsForZSet().removeRange("student",0,1);
        //根据分数区间删除
        redisTemplate.opsForZSet().removeRangeByScore("student",70,90);
        return "true";
    }





































}
